<?php
if(!defined('BASE_DIR'))die('Cannot access the file !');
/**
 * -+-----------------------------------------
 * |PHP Framework
 * |Copyright (c) 2010 jinke.[iblue.cc]
 * |E-mail: mejinke@gmail.com
 * |Date: 2011-08-13
 * -+-----------------------------------------
 *
 * MongoDB数据库Model模型基础类 ，所有MongoDB数据库的Model层都应继承此类
 * @author jinke
 */
class MongoModel extends Model
{



	/**
	 * 构造函数 主要用于初始化分配数据库连接资料
	 * @access public
	 * @param mixed $table_name 表名称或MODEL对象[可选]
	 * @param string $app_name 当前所在的应用程序名称
	 */
	public function __construct($table_name = '',$app_name='')
	{
		parent::__construct($table_name, $app_name);
		$this->getAppDefaultDataBaseName($app_name);
		$this->_dbType = MODEL_DB_TYPE_MONGODB;
		$this->getConnect();
		$this->clear();
		//记录操作数据库的MODEL名称
		Functions::RES('_MODEL_NAME_',$this->_tableName);
		Debug::initClass('mongo_model.class.php - '.get_class($this));
	}




	/**
	 * 添加数据到库中
	 * @access public
	 * @param array $data 添加的数据 [可选]
     * @param string $table 表名称 [可选]
     * @return mixed 查询结果
	 */
	public function insert(Array $data = null,$table='')
	{
		$this->setDbConnect('insert');
		if (empty($table))
			$table = $this->_tableName;
		Functions::RES('_MODEL_NAME_',strtolower($table));
		//检查如果不是自定义数据,则提交系统获取的数据
		/*$this->getForm($data);
		if (empty($this->_formData))
			return false;
		//检测是否验证通过
		if($this->_valiSuccess==$this->_valiSum)
		{	
			$this->_db->show_sql = $this->show_sql;
			return $this->_db->insert($this->_data,$table);
		}*/
		return $this->_db->insert($table, $data);
	 }


	/**
	 * 更新记录
	 * @access	public
	 * @param array $data 将要更新的数据数组 [可选]
	 * @param string $table 表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function update(Array $data = array(),$table='')
	{
		if ($this->adv_where=='')
			message_error('SQL Error','update操作不允许条件为空！',message_debug(debug_backtrace()));
		$this->setDbConnect('update');
		if (empty($table))
			$table = $this->_tableName;
		Functions::RES('_MODEL_NAME_',$table);
		$result = false ;
		//检查如果不是自定义数据,则提交系统获取的数据
		/*$this->getForm($data);
		if (empty($this->_formData))
			return false;
		//检测是否验证通过
		if($this->_valiSuccess==$this->_valiSum)
		{
			$this->_db->show_sql = $this->show_sql;
			$result = $this->_db->update($this->_data,$table,$this->adv_where);
		}*/
		$result = $this->_db->update($table, $this->adv_where, $data);
		$this->clear();
		return $result;
	}


	/**
	 * 删除记录
	 * @access public
	 * @param string $table 表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function remove($table='')
	{	
		if ($this->adv_where== array())
			message_error('SQL Error','remove操作不允许条件为空！',message_debug(debug_backtrace()));
		if (empty($table))
			$table = $this->_tableName;
		$this->setDbConnect('remove');
		Functions::RES('_MODEL_NAME_',$table);
		$result = $this->_db->remove($table, $this->adv_where);
		$this->clear();
		return $result;
	}


	/**
	 * 指定字段的值自动增加
	 * @access public
	 * @param string $field 字段名称，注：字段类型必需为int类型
	 * @param int $num 增加的数值 [可选]
	 * @param string $table 表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function autoAdd($field,$num=1,$table='')
	{
		if (empty($table))
			$table = $this->_tableName;
		$this->setDbConnect('update');
		Functions::RES('_MODEL_NAME_',$table);
		$result = $this->_db->updateNotSet($table, $this->adv_where,array('$inc'=>array($field=>$num)));
		$this->clear();
		return $result;

	}

	/**
	 * 指定字段的值自动减少
	 * @access public
	 * @param string $field	字段名称，注：字段类型必需为int类型
	 * @param int $num	增加的数值 [可选]
	 * @param string $table	表名称 [可选]
	 * @return mixed 查询结果
	 */
	public function autoLessen($field,$num=1,$table='')
	{
		if (empty($table))
			$table = $this->_tableName;
		$this->setDbConnect('update');
		Functions::RES('_MODEL_NAME_',$table);
		$result = $this->_db->updateNotSet($table, $this->adv_where,array('$inc'=>array($field=>-$num)));
		$this->clear();
		return $result;
	}



	/**
	 * 获取一行数据
	 * @access public
	 * @return mixed 查询结果
	 */
	public function getOne()
	{
		$this->adv_limit['start'] = 0;
		$this->adv_limit['offset'] = 1;
		if($result = $this->select())
			return $result[0];
		else
			return false;
	}

	/**
	 * 获取表中所有数据
	 * @access public
	 * @return mixed 查询结果
	 */
	public function getAll()
	{
		return $this->select();
	 }


	/**
	 * 分页获取数据
	 * @access public
	 * @param array|int	 $options
	 * size 每页显示数
	 * nowbar(true|false) 是否显示类似百度页码
	 * select(true|false) 下拉列表风格
	 * args 数组，重置参数
	 * url 重置的URL
	 * @return array
	 */
	public function getPage($option=array())
	{
		//当参数为int size时
		if(!is_array($option))
			$options['size']=$option;
		else
			$options=$option;

		//构造参数
		$autoPage = true;
		
		isset($options['size'])	? $size = $options['size'] : $size = 10;
		isset($options['nowbar']) ?	$nowbar	= $options['nowbar'] : $nowbar = false;
		isset($options['select']) ? $select	= $options['select'] : $select = false;
		isset($options['args']) ? $args	= $options['args'] : $args = $this->_router->getArgs();
		isset($options['url']) ? $url = $options['url'] : $url = '';
		isset($options['ajax']) ? $ajax = $options['ajax'] : $ajax = false;
		isset($options['parg'])	? $parg	= $options['parg'] : $parg = 'p';
		isset($options['autoPage']) ? $autoPage = $options['autoPage'] : true;
		
		//获取当前页码
		Functions::GET($parg) ? $p = Functions::GET($parg) : $p=1;
		if ($autoPage===false) $p=1;
			
		
		$nowbar=true;
		//获取总页
		$this->setDbConnect();
		$sum = $this->_db->getCount($this->_tableName, $this->adv_where);
		
		//URL是否存在页码
		$existsPage = false;
		if (isset($_GET[$parg]))
			$existsPage =true;
			
		//实例化Page对象
		$_p	= Functions::LIB('page');
		$_p->arg=$parg;
		$_p->ajax = $ajax;
		$_p->init($size,$sum,'',$args,$url);

		//获取当前页结果
		$this->limit(($p-1)*$size,$size);
		$result = $this->select();
		if ($existsPage && !isset($result[0]))
			message_404();
			
		//整理数据
		$data['data'] = $result;
		$data['pageArray'] = $_p->diyArray;
		if(!$nowbar)
			$data['html'] = $_p->show();
		else
			$data['html'] = $_p->nowbar();

		if($select)
			$data['html'].=' 跳转至：'.$_p->select();

		//返回内容
		return $data;
	 }



	/**
	 * 获取最后一次成生的ID
	 * @access public
	 * @return int
	 */
	public function getId()
	{
		//return $this->_db->getId();
	}

	/**
	 * 设置需要查询的列
	 * @access	public
	 * @param string $var 查询的列 例：id,name,age
	 * @return this
	 */
	public function find($var)
	{
		if(!empty($var))
			$this->adv_find = DBTool::findFormatFromMongoDB($var);
		return $this;
	 }

	/**
	 * 设置查询条件
	 * @access	public
	 * @param array $wheres 例：id=20
	 * @return this
	 */
	public function where(Array $wheres)
	{
		$tep = DBTool::whereFormatFromMongoDB($wheres);	 
		if (empty($this->adv_where))
			$this->adv_where = $tep;
		else
			$this->adv_where = array_merge($this->adv_where, $tep);
		return $this;
	}
	
	/**
	 * 追加条件
	 * @access public
	 * @param array $wheres
	 * @return this
	 */
	public function addWhere(Array $wheres){
		//兼容MYSQL驱动
		$this->where($wheres);	 	
		return $this;
	}
	

	/**
	 * 设置IN条件语句
	 * @access public
	 * @param string $field 字段 例：id
	 * @param array $array 条件值 例：array(1,3,4,23,5)
	 * @return this
	 */
	public function in($field = "", $array = array())
	 {
	 	$this->where_init($field);
	 	$this->adv_where[$field]['$in'] = $array;
	 	return $this;
	 }


	/**
	 * 设置NOT IN条件语句
	 * @access	public
	 * @param string $finds 字段 例：id
	 * @param array $array 条件值 例：array(1,3,4,23,5)
	 * @return this
	 */
	public function notIn($fields,Array $array = array(),$type = 'AND')
	{
		$this->where_init($field);
	 	$this->adv_where[$field]['$nin'] = $array;
	 	return $this;
	}


	/**
	 * 设置排序方式
	 * @access public
	 * @param string $var 例：id
	 * @return this
	 */
	public function order($var = array())
	{
		//兼容MYSQL语法，例 id desc,uid desc
		if(!is_array($var))
		{
			$tep = explode(',', $var);
			if (count($tep)>1)
			{	
				$var = array();
				for ($i=0; $i<count($tep); $i++)
				{
					$t = explode(' ', trim($tep[$i]));
					if (isset($t[0]) && isset($t[1]))
						$var[$t[0]] = $t[1];
				}
			}else 
			{ 
				$t = explode(' ', trim($var));
				if (isset($t[0]) && isset($t[1]))
				{
					$var = array();
					$var[$t[0]] = $t[1];
				}
			}
		}
	
		if (!is_array($var)) return $this;
	
		foreach($var as $col => $val)
	 	{
	 		if($val == -1 || $val === FALSE || strtolower($val) == 'desc')
	 		{
	 			$this->adv_order[$col] = -1; 
	 		}
	 		else
	 		{
	 			$this->adv_order[$col] = 1; 
	 		}
	 	}
		return $this;
	}

	/**
	 * 设置分组
	 * @access public
	 * @param string $str 字段
	 * @return this
	 */
	public function group($str)
	{
		if(!empty($str))
			$this->adv_group = ' GROUP BY '.$str;
		return $this;
	}

	/**
	 * 获取指定段的数据 Limit
	 * @access public
	 * @param int $start 开始位置
	 * @param int $offset 偏移量
	 * @return this
	 */
	public function limit($start, $offset)
	{

		if($start !== NULL && is_numeric($start))
	 	{
	 		$this->adv_limit['start'] = (int) $start;
	 	}
		if($offset !== NULL && is_numeric($offset))
	 	{
	 		$this->adv_limit['offset'] = (int) $offset;
	 	}
		return $this;
	}

	/**
	 * 执行查询
	 * @access public
	 * @param string $table 表名称［可选］
	 * @return mixed 查询结果
	 */
	public function select($table='')
	{ 
		if (empty($table))
			$table = $this->_tableName;
		Functions::RES('_MODEL_NAME_',$this->_tableName);
		$this->setDbConnect();
		$result = $this->_db->select($table, $this->adv_find, $this->adv_where, $this->adv_limit, $this->adv_order);
		$this->clear();
		return $this->setSelectDataType($result);
	}
	
	
	/**
	 * 确保条件字段存在
	 * @param string $param
	 */
	private function where_init($param)
	{
		if(!isset($this->adv_where[$param]))
			$this->adv_where[$param] = array();
	}
	
	

	/**
	 * 执行查询后，重置相关属性
	 * @access private
	 * @return void
	 */
	private function clear()
	{
		//重置SQL属性
		$this->adv_find = array();
		$this->adv_where = array();
		$this->adv_in = array();
		$this->adv_not_in =array();
		$this->adv_order = array();
		$this->adv_group = array();
		$this->adv_limit =array();

	}

}
?>